
package com.hlkj.pay.gateway.order.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.extension.executor.ExtensionExecutor;
import com.hlkj.framework.extension.scenario.BizScenario;
import com.hlkj.pay.app.merchant.ext.ChannelMerchantTransferExtPt;
import com.hlkj.pay.app.merchant.ext.MerchantExtConstant;
import com.hlkj.pay.app.merchant.ext.dto.payment.ChannelTransferContext;
import com.hlkj.pay.common.constants.MerchantConstant;
import com.hlkj.pay.dto.order.NotifyOrderTransferDto;
import com.hlkj.pay.dto.order.OrderTransferVerifyDto;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.gateway.order.IChannelTransferGateway;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAppChannelDO;
import com.hlkj.pay.infrastructure.model.order.OrderTransferDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelConfigDO;
import com.hlkj.pay.service.merchant.IMerchantApplicationService;
import com.hlkj.pay.service.pay.IProviderService;

import jodd.util.StringPool;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2025/02/08 16:49
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ChannelTransferGatewayImpl implements IChannelTransferGateway {

    @Value("${hlkj.pay.barrier:false}")
    private boolean barrier;

    @Value("${hlkj.pay.test:false}")
    private boolean test;

    @Value("${hlkj.domain}")
    private String domain;

    private final ExtensionExecutor extensionExecutor;

    private final IMerchantApplicationService merchantApplicationService;

    private final IProviderService providerService;

    @Override
    public CommonResult<NotifyOrderTransferDto> orderStatusParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        return extensionExecutor.execute(ChannelMerchantTransferExtPt.class, BizScenario.valueOf(providerChannelConfigDO.getChannelCode()),
                ex -> ex.orderTransferStatusParse(request, providerChannelConfigDO));
    }

    @Override
    public boolean extensionExist(String channelCode) {
        return extensionExecutor.executeExist(ChannelMerchantTransferExtPt.class, BizScenario.valueOf(channelCode));
    }

    @Override
    public boolean autoWithdraw(String channelCode) {
        return false;
    }

    @Override
    public OrderTransferDO queryChannelOrder(OrderTransferDO orderTransferDO) {
        if (barrier) {
            OrderTransferDO orderTransfer = new OrderTransferDO();
            orderTransfer.setStatus(MerchantEnum.PROCESS_STATUS.SUCCESS.getCode());
            log.info("测试环境渠道不生成特殊订单号返回成功 payOrderNo:{}", orderTransferDO.getPayOrderNo());
            return orderTransfer;
        }
        MerchantAppChannelDO merchantAppChannelDO = merchantApplicationService.queryAppChannelDetail(orderTransferDO.getMchChannelCode());
        ChannelTransferContext channelTransferContext = new ChannelTransferContext();
        channelTransferContext.setMerchantAppChannelDO(merchantAppChannelDO);
        channelTransferContext.setOrderTransfer(orderTransferDO);
        channelTransferContext.setProviderChannelConfig(providerService.queryConfig(merchantAppChannelDO.getProviderCode(), merchantAppChannelDO.getChannelCode()));
        channelTransferContext.setTest(test);
        extensionExecutor.executeVoid(ChannelMerchantTransferExtPt.class, BizScenario.valueOf(merchantAppChannelDO.getChannelCode()),
                ex -> ex.queryChannelTransfer(channelTransferContext));
        if (channelTransferContext.isProcessStatus()) {
            return channelTransferContext.getUpdateOrderTransfer();
        }
        OrderTransferDO orderTransfer = new OrderTransferDO();
        orderTransfer.setStatus(MerchantEnum.PROCESS_STATUS.FAIL.getCode());
        orderTransfer.setMessage(channelTransferContext.getRemark());
        return orderTransfer;
    }

    @Override
    public CommonResult<OrderTransferDO> submitChannelOrderApply(MerchantAppChannelDO merchantAppChannelDO, OrderTransferDO orderTransferDO) {
        if (barrier) {
            OrderTransferDO orderTransfer = new OrderTransferDO();
            orderTransfer.setStatus(MerchantEnum.PROCESS_STATUS.SUCCESS.getCode());
            log.info("测试环境提交转账预订单 返回成功 payOrderNo:{}", orderTransferDO.getPayOrderNo());
            return CommonResult.success(orderTransfer);
        }
        MerchantAppChannelDO inMerchantAppChannelDO = merchantApplicationService.queryAppChannelDetail(orderTransferDO.getInMchChannelCode());
        ChannelTransferContext channelTransferContext = new ChannelTransferContext();
        channelTransferContext.setMerchantAppChannelDO(merchantAppChannelDO);
        channelTransferContext.setOrderTransfer(orderTransferDO);
        channelTransferContext.setProviderChannelConfig(providerService.queryConfig(merchantAppChannelDO.getProviderCode(), merchantAppChannelDO.getChannelCode()));
        channelTransferContext.setTest(test);
        channelTransferContext.setInMerchantAppChannelDO(inMerchantAppChannelDO);
        channelTransferContext.setNotifyUrl(
                domain + MerchantExtConstant.MERCHANT_TRANSFER_TRANS_ASYNC_CALLBACK_URL + orderTransferDO.getChannelCode() + StringPool.SLASH + orderTransferDO.getProviderCode());
        channelTransferContext.setPassword(MerchantConstant.REPORT_PASSWORD);
        extensionExecutor.executeVoid(ChannelMerchantTransferExtPt.class, BizScenario.valueOf(merchantAppChannelDO.getChannelCode()),
                ex -> ex.submitChannelSingleTransferApply(channelTransferContext));
        if (channelTransferContext.isProcessStatus()) {
            return CommonResult.success(channelTransferContext.getUpdateOrderTransfer());
        }
        return CommonResult.error(1, channelTransferContext.getRemark());
    }

    @Override
    public CommonResult<OrderTransferDO> submitTransferOrder(OrderTransferVerifyDto orderTransferVerifyDto, OrderTransferDO orderTransferDO) {
        if (barrier) {
            OrderTransferDO orderTransfer = new OrderTransferDO();
            orderTransfer.setStatus(MerchantEnum.PROCESS_STATUS.SUCCESS.getCode());
            log.info("测试环境提交转账订单 返回成功 payOrderNo:{}", orderTransferDO.getPayOrderNo());
            return CommonResult.success(orderTransfer);
        }
        MerchantAppChannelDO inMerchantAppChannelDO = merchantApplicationService.queryAppChannelDetail(orderTransferDO.getInMchChannelCode());
        MerchantAppChannelDO outMerchantAppChannelDO = merchantApplicationService.queryAppChannelDetail(orderTransferDO.getMchChannelCode());
        ChannelTransferContext channelTransferContext = new ChannelTransferContext();
        channelTransferContext.setMerchantAppChannelDO(outMerchantAppChannelDO);
        channelTransferContext.setInMerchantAppChannelDO(inMerchantAppChannelDO);
        channelTransferContext.setOrderTransfer(orderTransferDO);
        channelTransferContext.setOrderTransferVerifyDto(orderTransferVerifyDto);
        channelTransferContext.setProviderChannelConfig(providerService.queryConfig(outMerchantAppChannelDO.getProviderCode(), outMerchantAppChannelDO.getChannelCode()));
        channelTransferContext.setTest(test);
        channelTransferContext.setInMerchantAppChannelDO(inMerchantAppChannelDO);
        channelTransferContext.setNotifyUrl(
                domain + MerchantExtConstant.MERCHANT_TRANSFER_TRANS_ASYNC_CALLBACK_URL + orderTransferDO.getChannelCode() + StringPool.SLASH + orderTransferDO.getProviderCode());
        channelTransferContext.setPassword(MerchantConstant.REPORT_PASSWORD);
        extensionExecutor.executeVoid(ChannelMerchantTransferExtPt.class, BizScenario.valueOf(outMerchantAppChannelDO.getChannelCode()),
                ex -> ex.submitChannelSingleTransfer(channelTransferContext));
        if (channelTransferContext.isProcessStatus()) {
            return CommonResult.success(channelTransferContext.getUpdateOrderTransfer());
        }
        return CommonResult.error(1, channelTransferContext.getRemark());
    }


}
